/*************************************************
Author: will
Date: 11/8/2012
Description:
Notes:
*************************************************/

#ifndef __CRandom_h__
#define __CRandom_h__

#include "CTHashObjectMgr.h"
#include "CTRandomNum.h"
#include "CTArray.h"

class CRateTarget
{
public:
    enum
    {
        TARGET_INFINITY = -1,
    };

    CRateTarget()
        :_iTargetID(0), _iMaxCount(0), _iRate(0), _iDropCount(0), _iData1(0), _iData2(0), _iData3(0), _iData4(0)
    {

    }

    virtual ~CRateTarget()
    {

    }

public:
    int _iTargetID;           // 对应具体的掉落物品
    int _iMaxCount;           // 掉落上限
    int _iRate;               // 掉落概率
    int _iDropCount;          // 累计掉落数量

    int _iData1;
    int _iData2;
    int _iData3;
    int _iData4;
};

template<int COUNT>
class CRandomSet
{
public:
    CRandomSet()
        : _iRateMax(0)
    {

    }

    virtual ~CRandomSet()
    {
        Clear();
    }

    int Add(CRateTarget& stTarget)
    {
        if (stTarget._iRate <= 0 || stTarget._iMaxCount == 0)
        {
            return 0;
        }

        _astDropArray.AddOneItem(stTarget);
        _iRateMax += stTarget._iRate;

        return 0;
    }

    int Del(int iTargetID)
    {
        for (int i = 0; i < _astDropArray.Size(); ++i)
        {
            if (_astDropArray[i]._iTargetID == iTargetID)
            {
                _astDropArray.DelOneItem(i);
                _iRateMax = GetMax();
                if (_iRateMax < 0)
                {
                    _iRateMax = 0;
                }
                return 0;
            }
        }

        return 0;
    }

    int AddDropCount(CRateTarget& stTarget)
    {
        if (stTarget._iDropCount <= 0)
        {
            return 0;
        }

        for (int i = 0; i < _astDropArray.Size(); ++i)
        {
            if (_astDropArray[i]._iTargetID == stTarget._iTargetID)
            {
                if (_astDropArray[i]._iMaxCount != CRateTarget::TARGET_INFINITY)
                {
                    _astDropArray[i]._iDropCount += stTarget._iDropCount;

                    if (_astDropArray[i]._iDropCount >= _astDropArray[i]._iMaxCount)
                    {
                        //清理
                        Del(_astDropArray[i]._iTargetID);
                    }
                }

                return 0;
            }
        }

        return 0;
    }

    int DropOne(CRateTarget& stDrop)
    {
        if (_iRateMax <= 0)
        {
            CT_ERROR((""));
            return -1;
        }

        //根据 _iRateMax 算概率
        unsigned int iActRate = CT_RANDOM_NUM->GetRand((unsigned int)_iRateMax);

        //遍历所有target
        unsigned int iRateSum = 0;
        for (int i = 0; i < _astDropArray.Size(); ++i)
        {
            CRateTarget& stRateTarget = _astDropArray[i];
            if (iRateSum <= iActRate && iRateSum + stRateTarget._iRate > iActRate) //确定target
            {
                stDrop = stRateTarget;
                if (stRateTarget._iMaxCount != CRateTarget::TARGET_INFINITY)
                {
                    stRateTarget._iDropCount++;

                    if (stRateTarget._iDropCount >= stRateTarget._iMaxCount)
                    {
                        //清理
                        Del(stRateTarget._iTargetID);
                    }
                }

                return 0;
            }

            iRateSum += stRateTarget._iRate;
        }

        CT_ERROR(("%d, %d", iActRate, iRateSum));
        return -1;
    }

    int Clear()
    {
        _iRateMax = 0;
        _astDropArray.Clear();
        return 0;
    }

    int GetMax()
    {
        int iRateSum = 0;

        for (int iIndex = 0;
            iIndex < _astDropArray.Size();
            ++iIndex)
        {
            iRateSum += _astDropArray[iIndex]._iRate;
        }

        return iRateSum;
    }

    int GetTargetCnt ()
    {
        return _astDropArray.Size();
    }

protected:
    int _iRateMax;    //掉落概率累计值，用来做随机
    CTLib::CTArray<CRateTarget, COUNT> _astDropArray;
};


#endif // __CRandom_h__

